﻿//
// SettingsForm.cs: Form for managing settings for application and plugins.
//
// Copyright 2010 Michael Goethe
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using S9PalCommon;

namespace S9Pal
{
    /// <summary>
    /// Form for managing settings for application and plugins.
    /// </summary>
    public partial class SettingsForm : Form
    {
        #region Fields

        List<ISettingsControl> settingsControls;

        #endregion

        #region Constructors

        public SettingsForm()
        {
            InitializeComponent();
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Search through plugins for SettingsControls and add them to a list. Also add each control
        /// to the list box.
        /// </summary>
        private void LoadPluginsAndPopulateListBox()
        {
            settingsControls = new List<ISettingsControl>();

            AddSettingsControl(new ApplicationSettingsControl());

            // Find SettingsControls in each plugin.
            foreach (AvailablePlugin plugin in Global.Plugins.AvailablePlugins)
            {
                foreach (ISettingsControl sc in plugin.Instance.SettingsControls)
                {
                    AddSettingsControl(sc);
                }
            }

            // If there's at least one item in the list box, select the first item.
            if (settingsPageListBox.Items.Count > 0)
                settingsPageListBox.SelectedIndex = 0;
        }

        /// <summary>
        /// Adds a SettingsControl to the list.
        /// </summary>
        /// <param name="settingsControl">SettingsControl to add.</param>
        private void AddSettingsControl(ISettingsControl settingsControl)
        {
            // Add the control to our list.
            settingsControls.Add(settingsControl);

            // Add a new item to the list box with the DisplayTitle specified in the SettingsControl.
            settingsPageListBox.Items.Add(settingsControl.DisplayTitle);

            // Tell the SettingsControl to update the values of its controls so that they reflect the actual current values
            // of the settings.
            settingsControl.UpdateControlValues();
        }

        #endregion

        #region Events

        private void applyButton_Click(object sender, EventArgs e)
        {
            // Attempt to apply (save) the settings.
            foreach (ISettingsControl sc in settingsControls)
            {
                try
                {
                    sc.ApplySettings();
                    
                }
                catch (ArgumentException ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void cancelButton_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void okButton_Click(object sender, EventArgs e)
        {
            // Attempt to apply (save) the settings and close the form.
            foreach (ISettingsControl sc in settingsControls)
            {
                try
                {
                    sc.ApplySettings();
                }
                catch (ArgumentException ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }

            this.Close();
        }

        private void SettingsForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            (this.Owner as MainForm).UpdateDeviceStatus();

            // Make sure we clear out the settings panel. Otherwise our control will get stuck to the previous instance.
            settingsPanel.Controls.Clear();
        }

        private void SettingsForm_Load(object sender, EventArgs e)
        {
            LoadPluginsAndPopulateListBox();
        }        
        
        private void settingsPageListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Clear the panel displaying the current SettingsControl.
            settingsPanel.Controls.Clear();

            // Add the new SettingsControl to the panel, as selected by the user.
            settingsPanel.Controls.Add((UserControl)settingsControls[settingsPageListBox.SelectedIndex]);

            // Update the name label displayed above the current SettingsControl.
            nameLabel.Text = settingsControls[settingsPageListBox.SelectedIndex].DisplayTitle;
        }

        #endregion
    }
}
